package com.dagger.utils;

import java.lang.reflect.Field;
import java.lang.reflect.Method;
import java.util.List;

import org.apache.commons.lang3.ArrayUtils;

import com.alibaba.fastjson2.JSONArray;
import com.alibaba.fastjson2.JSONObject;

/**
 * 对象工具类
 * @author dagger
 *
 */
public class LocalBeanUtils {
	
	/**
	 * 判断一个对象是否是空
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Object obj) {
		if(obj == null) {
			return true;
		}
		
		if(obj.getClass().isEnum()) {
			return false;
		}
		
		switch(obj.getClass().getSimpleName()) {
		case "LinkedList":
		case "ArrayList":
			return ((List<?>)obj).isEmpty();
		case "String":
			return ((String)obj).trim().length()==0;
		case "String[]":
			String[] ary = (String[])obj;
			if(ary.length == 0) {
				return true;
			}
			for(String str:ary) {
				if(!isEmpty(str)) {
					return false;
				}
			}
			return true;
		case "JSONArray":
			return ((JSONArray)obj).isEmpty();
		case "JSONObject":
			return ((JSONObject)obj).isEmpty();
		case "Date":
		case "Long":
		case "Integer":
		case "Double":
		case "Float":		
		case "BigDecimal":
			return false;//可能需要继续完善类型
		default:{
			if(obj.getClass().isPrimitive()) {
				//基础类型，直接返回
				return false;
			}
		}
		}
		
		Field[] fields = getFields(obj.getClass());
		if(fields == null || fields.length == 0) {
			return true;
		}
				
		for(Field field:fields) {
			if(!isEmpty(field,obj)) {
				return false;
			}
		}
		
		return true;
	}
	
	/**
	 * 判断一个属性是否为空
	 * @param field
	 * @param obj
	 * @return
	 */
	public static boolean isEmpty(Field field,Object obj) {
		if(obj == null || field == null) {
			return true;
		}
		
		String getMethodName = getGetMethodName(field.getName());
		try {
			Method getMethod = obj.getClass().getDeclaredMethod(getMethodName);
			Object fieldValue = getMethod.invoke(obj);
			return isEmpty(fieldValue);
		} catch (Exception e) {
		}
		
		return true;
	}
	
	/**
	 * 获取对象属性的的GET方法名称
	 * @param fieldName
	 * @return
	 */
	public static String getGetMethodName(String fieldName) {
		if(fieldName==null || fieldName.length()==0) {
			throw new RuntimeException("fieldName不能为空");
		}
		String getMethodName = "get"+fieldName.substring(0,1).toUpperCase();
		if(fieldName.length()>1) {
			getMethodName+=fieldName.substring(1);
		}
		return getMethodName;
	}
	
	/**
	 * 获取对象属性的的GET方法名称
	 * @param fieldName
	 * @return
	 */
	public static String getSetMethodName(String fieldName) {
		if(fieldName==null || fieldName.length()==0) {
			throw new RuntimeException("fieldName不能为空");
		}
		String getMethodName = "set"+fieldName.substring(0,1).toUpperCase();
		if(fieldName.length()>1) {
			getMethodName+=fieldName.substring(1);
		}
		return getMethodName;
	}
	
	/**
	 * 获取所有的属性，包括继承的的属性
	 * @param c
	 * @return
	 */
	public static Field[] getFields(Class<?> c) {
		if(c == Object.class) {
			return null;
		}
		
		Field[] fields = c.getDeclaredFields();
		Field[] superFields = getFields(c.getSuperclass());
		if(superFields == null) {
			return fields;
		}
		return (Field[])ArrayUtils.addAll(fields, superFields);
	}
	
	@SuppressWarnings("unchecked")
	public static <T> T trim(T obj) {
		if(obj == null) {
			return null;
		}
		
		if(obj.getClass().isArray()) {
			Object[] ary = (Object[])obj;
			for(int i=0;i<ary.length;i++) {
				ary[i]=trim(ary[i]);
			}
			return (T)ary;
		}
		
		Field[] fields = getFields(obj.getClass());
		if(fields == null || fields.length == 0) {
			return obj;
		}
				
		for(Field field:fields) {
			String getMethodName = getGetMethodName(field.getName());
			String setMethodName = getSetMethodName(field.getName());
			try {
				Method getMethod = obj.getClass().getDeclaredMethod(getMethodName);
				if(getMethod == null) {
					continue;
				}
				Object fieldValue = getMethod.invoke(obj);
				if(fieldValue != null) {
					Method setMethod = obj.getClass().getDeclaredMethod(setMethodName,field.getType());
					setMethod.invoke(obj, trim(fieldValue));
				}
			} catch (Exception e) {
			}
		}
		
		return obj;
	}
	
	/**
	 * 判断多个对象是否全为空
	 * @param objs
	 * @return
	 */
	public static boolean isAllEmpty(Object... objs) {

		if(objs == null || objs.length == 0) {
			return true;
		}
		
		for(Object obj:objs) {
			if(!isEmpty(obj)) {
				return false;
			}
		}
		return true;
	}
	
	/**
	 * 判断多个对象是否有一个为空
	 * @param objs
	 * @return
	 */
	public static boolean isSomeOneEmpty(Object... objs) {

		if(objs == null || objs.length == 0) {
			return true;
		}
		
		for(Object obj:objs) {
			if(isEmpty(obj)) {
				return true;
			}
		}
		return false;
	}

	/**
	 * 
	 * @Title: emptyToNull
	 * @Description:  将空的属性置为null
	 * @param @param entity    设定文件
	 * @return void    返回类型
	 * @throws
	 */
	@SuppressWarnings("unchecked")
	public static <T> T emptyToNull(T obj) {
		if(isEmpty(obj)) {
			return null;
		}
		
		if(obj.getClass().isArray()) {
			Object[] ary = (Object[])obj;
			for(int i=0;i<ary.length;i++) {
				ary[i]=emptyToNull(ary[i]);
			}
			return (T)ary;
		}
		
		switch(obj.getClass().getSimpleName()) {
		case "LinkedList":
		case "ArrayList":
			((List<Object>)obj).forEach(item ->{
				item = emptyToNull(item);
			});
			return obj;		
		case "String":
			return (T)((String)obj).trim();
		case "Date":
		case "Long":
		case "Double":
		case "Float":
		case "BigDecimal":
			return obj;//可能需要继续完善类型
		default:{
			if(obj.getClass().isPrimitive()) {
				//基础类型，直接返回
				return obj;
			}
		}
		}
		
		Field[] fields = getFields(obj.getClass());
		if(fields == null || fields.length == 0) {
			return obj;
		}
				
		for(Field field:fields) {
			String getMethodName = getGetMethodName(field.getName());
			String setMethodName = getSetMethodName(field.getName());
			try {
				Method getMethod = obj.getClass().getDeclaredMethod(getMethodName);
				if(getMethod == null) {
					continue;
				}
				Object fieldValue = getMethod.invoke(obj);
				if(fieldValue != null) {
					Method setMethod = obj.getClass().getDeclaredMethod(setMethodName,field.getType());
					setMethod.invoke(obj, emptyToNull(fieldValue));
				}
			} catch (Exception e) {
			}
		}
		
		return obj;
		
	}
	
	/**
	 * 
	 * @Title: getCamelCaseName
	 * @Description: 获取驼峰名字
	 * @param @param columnName
	 * @param @return    设定文件
	 * @return String    返回类型
	 * @throws
	 */
	public static String getCamelCaseName(String columnName) {
		String temp[] = columnName.toLowerCase().split("_");
		columnName = temp[0];
		for(int i=1;i<temp.length;i++) {
			columnName+=LocalStringUtils.getFirstUpString(temp[i]);
		}
		return columnName;
	}
}
